#!/usr/bin/env python
# -*- coding: utf-8 -*-

import md5
import os, os.path, sys
import tempfile

import unittest

from potherb import log
from potherb.key import ROW_KEY_MIN,ROW_KEY_MAX
from potherb.rangeserver import RangeServer
from potherb.scan import ScanContext,ScanSpec

class   TestRangeServer_001(unittest.TestCase) :

    def setUp(self) :
        self.range_root_dir = tempfile.mkdtemp(suffix='.dir', prefix='range-')
        log.debug('range-root-dir:%s', self.range_root_dir)
        # setUp()

    def removeDirs(self, dir_name) :
        items = os.listdir(dir_name)
        for item in items :
            dir_item = '%s/%s' % (dir_name, item)
            if os.path.isdir(dir_item) :
                self.removeDirs(dir_item)
            else :
                os.remove(dir_item)
        if os.path.exists(dir_name) :
            os.removedirs(dir_name)
        # removedirs()

    def tearDown(self) :
        if os.path.exists(self.range_root_dir) :
            self.removeDirs(self.range_root_dir)
        # tearDown()

    def NtestRange_001(self) :
        table_name = 'test'
        range_begin_row = 'aaaaaa'
        range_end_row   = 'zzzzzz'

        rs = RangeServer(self.range_root_dir)

        ok = rs.hasRange(table_name, range_begin_row, range_end_row)
        self.assertFalse(ok)
        ok = rs.hasRange(table_name, range_begin_row)
        self.assertFalse(ok)

        rs.createRange(table_name, range_begin_row, range_end_row)
        rs.openRange(table_name, range_begin_row, range_end_row)
        rs.closeRange(table_name, range_begin_row, range_end_row)

        ok = rs.hasRange(table_name, range_begin_row, range_end_row)
        self.assertTrue(ok)
        ok = rs.hasRange(table_name, range_begin_row)
        self.assertTrue(ok)

        rs.dropRange(table_name, range_begin_row, range_end_row)

        ok = rs.hasRange(table_name, range_begin_row, range_end_row)
        self.assertFalse(ok)
        ok = rs.hasRange(table_name, range_begin_row)
        self.assertFalse(ok)

        # testRange_001

    def NtestRange_002(self) :
        table_name = 'test'
        range_begin_row = ROW_KEY_MIN
        range_end_row   = ROW_KEY_MAX

        rs = RangeServer(self.range_root_dir)

        ok = rs.hasRange(table_name, range_begin_row, range_end_row)
        self.assertFalse(ok)
        ok = rs.hasRange(table_name, range_begin_row)
        self.assertFalse(ok)

        rs.createRange(table_name, range_begin_row, range_end_row)
        rs.openRange(table_name, range_begin_row, range_end_row)
        rs.closeRange(table_name, range_begin_row, range_end_row)

        ok = rs.hasRange(table_name, range_begin_row, range_end_row)
        self.assertTrue(ok)
        ok = rs.hasRange(table_name, range_begin_row)
        self.assertTrue(ok)

        rs.dropRange(table_name, range_begin_row, range_end_row)

        ok = rs.hasRange(table_name, range_begin_row, range_end_row)
        self.assertFalse(ok)
        ok = rs.hasRange(table_name, range_begin_row)
        self.assertFalse(ok)

        # testRange_002

    def testRange_003(self) :
        table_name = 'test'
        range_begin_row = 'AAAAAA'
        range_end_row   = 'ZZZZZZ'

        rs = RangeServer(self.range_root_dir)
        rs.createRange(table_name, range_begin_row, range_end_row)
        rs.openRange(table_name, range_begin_row)

        test_set_one = ('AAAAAA', 'BBBBBB', 'CCCCC', 'ZZZZZZ')
        # insert
        for k in test_set_one :
            v = 'VALUE:%s' % k
            row_key = k
            columns = [ ('tag', 'sarah', v) ]
            rs.insert(table_name, row_key, columns)

        # find
        scan_timeout = 10
        for k in test_set_one :
            row_key = k

            log.debug('testing KEY=%s',row_key)
            scan_spec = ScanSpec()
            scan_spec.setRow(row_key)
            scan_context = ScanContext()
            scan_context.scan_spec = scan_spec

            count_records = 0
            scanner = rs.createScanner(table_name, scan_context, scan_timeout)
            try :
                for key,data,timestamp in scanner :
                    log.debug('QUERY key:%s data:%s timestamp:%d', key, data, timestamp)
                    self.assertEqual(row_key, key)
                    count_records += 1
            except StopIteration :
                pass
            except :
                log.excpt()
            finally :
                if count_records < 1 :
                    self.fail('%d records scanned, ONLY 1 expected.' % count_records)
                if count_records > 1 :
                    self.fail('%d records scanned, ONLY 1 expected.' % count_records)

        # erase the row
        for k in test_set_one :
            row_key = k
            rs.erase(table_name, row_key)

        # find again
        scan_timeout = 10
        for k in test_set_one :
            row_key = k

            scan_spec = ScanSpec()
            scan_spec.setRow(row_key)
            scan_context = ScanContext()
            scan_context.scan_spec = scan_spec

            count_records = 0
            scanner = rs.createScanner(table_name, scan_context, scan_timeout)
            try :
                for key,data,timestamp in scanner :
                    log.debug('QUERY key:%s data:%s timestamp:%d', key, data, timestamp)
                    self.assertEqual(row_key, key)
                    count_records += 1
            except StopIteration :
                pass
            except :
                log.excpt()
            finally :
                if count_records > 0 :
                    self.fail('%d records scanned, ONLY 0 expected.' % count_records)

        rs.closeRange(table_name, range_begin_row)
        rs.dropRange(table_name, range_begin_row)
        del rs
        rs = None
        # testRange_003()

    def testRange_004(self) :
        table_name = 'test'
        range_begin_row = 'AAAAAA'
        range_end_row   = 'ZZZZZZ'

        rs = RangeServer(self.range_root_dir)
        rs.createRange(table_name, range_begin_row, range_end_row)
        rs.openRange(table_name, range_begin_row)

        test_set_one = ('AAAAAAAAA', 'AAA', 'ZZZ', 'ZZZZZZZZZ')
        # insert


        # find

        # erase

        # find again

        rs.closeRange(table_name, range_begin_row)
        rs.dropRange(table_name, range_begin_row)
        del rs
        rs = None
        # testRange_004()

    # class TestRangeServer_001

#######################################################################

if  __name__ == '__main__' :
    #log.setLogPath('/dev/null')
    log.enableDebug()

    unittest.main()
